/* hrfsLibP.h - Highly reliabe file system private header file */

/*
 * Copyright 2005 Wind River Systems, Inc.
 *
 * The right to copy, distribute, modify or otherwise make use
 * of this software may be licensed only pursuant to the terms
 * of an applicable Wind River license agreement.
 */
 
/* modification history
--------------------
02n,04aug05,jlk  Moved formatter function pointer, hrfsFmtRtn, to hrFsLib.h
02m,22jul05,jlk  code review changes
02l,18jul05,jlk  Added formatter function pointer, hrfsFmtRtn
02k,28jun05,jlk  clean-up and added diskModified flag to volume descriptor
02j,17jun05,jlk  removed prototype for hrfsXbdSyncDone()
02i,17may05,pcm  added hrfsTransactionRollback()
02h,29apr05,jlk  moved in CRC #defines from hrFsSuperBlk.c. Added inode state 
                 defines. Fixed bug where the generation field in the inode was
                 defined to be 8 bytes instead of 4. Added <state> field to
                 inode. Added some prototypes.
02g,25apr05,jlk  moved version #defines and id string to hrFsLib.h and fixed 
                 endian check
02f,21apr05,jlk  added freeInodes and freeDataBlks fields to TMR. Re-arranged 
                 volume descriptor for alignment purposes and removed unused 
                 fields. Added prototypes for hrfsMount() and hrfsStat()
02e,15apr05,pcm  added <numInodesToDelete> field to HRFS_TMR
02d,15apr05,act  add a dirSlot to HRFS_INODE (incore inode)
02c,14apr05,pcm  changed INODE_JOURNAL_ENTRIES from 4 to 7
02b,14apr05,pcm  removed HRFS_MODE_BIT_xxx; the S_IFxxx definitions to be used
02a,11apr05,pcm  changed DIRENT's field  fileName string size to
                 HRFS_DIRENT HRFS_MAX_FILENAME_LEN + 1
01z,24mar05,jlk  added prototype for hrfsCommit()
01y,23mar05,jlk  debug stuff and moved nBlocks field in inode structure
01x,21mar05,jlk  moved nBlocks field in inode structure for alignment reasons
01v,21mar05,jlk  fixed bug in big endian versions of htodll and dtohll macros
                 and added padding to super block structure to make the size
                 a multiple of 8.
01u,16mar05,pcm  changed parameters to hrfsInodeGet()
01t,15mar05,pcm  made htodll() a function call to htodll_le() for little endian
01s,15mar05,pcm  reworked htodll() and dtohll() macros
01r,10mar05,act  remove unwanted data from HRFS_DEV
01q,08mar05,jlk  fixed up for new mount code
01p,08mar05,jlk  changed prototype for hrfsInodeAlloc()
01o,07mar05,pcm  added VTOI macro and various function prototypes
01n,07mar05,jlk  added mode bits for inode
01m,01mar05,jlk  removed pointer to the inode journal to 
                 HRFS_VOLUME_DESC. Added some more prototypes.
01l,28feb05,pcm  added HRFS_INODE_ROOT_DIR
01k,25feb05,pcm  changed iNodeNunber to iNodeNumber in INODE_JOURNAL
01j,24feb05,pcm  added mount.h to includes, and new fields to HRFS_VOLUME_DESC
01i 24feb05,jlk  added nBlocks and reserved fields to inode structure
01h 23feb05,jlk  added a pointer to the inode journal to HRFS_VOLUME_DESC.
                 added transaction numbers to HRFS_VOLUME_DESC
01g 11feb05,pcm  added HRFS_TMR structure, and fields to HRFS_VOLUME_DESC
01f,09feb05,jlk  added sectorsPerBlk & sectorsPerBlk2 fields to the 
                 HRFS_VOLUME_DESC structure
01e,03feb05,pcm  changed HRFS_SUPER_BLOCK field in HRFS_VOLUME_DESC to a ptr
01c,03feb05,jlk  updated inode struct to include an on-disk and an in-memory 
                 version
01b,26jan05,pcm  added HRFS_DEV structure
01a,21jan05,jlk  written
*/

#ifndef __INChrfsLibP
#define __INChrfsLibP

#include <vxWorks.h>
#include <hrFsLib.h>
#include <netinet/in.h>
#include <drv/xbd/bio.h>
#include <mount.h>
#include <vnode.h>

/* defines */
/*#define HRFS_DEBUG*/

#ifdef HRFS_DEBUG
#define HRFS_DEBUGM(x) x
#else
#define HRFS_DEBUGM(x)
#define hrfsInodePrint(x,y)
#define hrfsPrintSuperBlk(x)
#define hrfsPrintSuperBlkRaw(x)
#define hrfsPrintBmp(x,y)
#endif

/* The number of inodes in the journal */
#define INODE_JOURNAL_ENTRIES 7

/* The number that represents an invalid block */
#define INVALID_BLK_NUM       ((UINT32)(-1))

#define HRFS_VOLUME_MAGIC  (0x00a87cb7)

/* CRC */
#define HRFS_INTIAL_CRC32  0xffffffff  /* Initial 32 bit FCS value */
#define HRFS_GOOD_CRC32    0xdebb20e3  /* Good final 32 bit FCS value */

/* Inode states */
#define HRFS_INODE_STATE_FREE      0xFF
#define HRFS_INODE_STATE_ALLOC     0xFE
#define HRFS_INODE_STATE_TO_BE_DEL 0xFC

/* Reserved inode numbers */
#define INODE_START_NUMBER   2
#define HRFS_INODE_ROOT_DIR  INODE_START_NUMBER


/* Macro to get inode from vnode */
#define HRFS_VTOI(ip,vnp) \
    ip = (VTODATA(HRFS_INODE, vnp));  \
    ip->iNodeNumber = vnp->v_inode;
    

/* 
 * Byte swap macros for converting in memory representations to disk
 * representations for various types.
 */

/* Use network macros for shorts and longs */
#define dtohs  ntohs
#define dtohl  ntohl
#define htods  htons
#define htodl  htonl
/* For long, longs or 64 bit quantities we need our own macros */
#if (_BYTE_ORDER == _BIG_ENDIAN)
/* 
 * Nothing to do for big endian targets since HRFS on-disk format is big endian
 */
#define dtohll(x) (x)
#define htodll(x) (x)

#else /* Handle little endian case */

extern  UINT64 htodll_le (UINT64);

#define htodll(x)    htodll_le(x)
#define dtohll(x)    htodll(x)

#endif /* _BYTE_ORDER==BIG_ENDIAN */

/* 
 * Macro to determine the numnber of inodes per block based on a 64 byte sized 
 * inode 
 */
#define INODES_PER_BLK(bsize) ((bsize) >> 6)

/* Macro to round up the number of inodes based on inodes per block */
#define NUM_INODES_UP(iperblk, ni) ((iperblk) + (((ni) - 1) & (-(iperblk))))

/* 
 * Macro to convert bytes to blocks based on a block size specified as a power 
 * of 2 
 */
#define BYTES_TO_BLKS(bytes, blkSize2) ((bytes) >> (blkSize2))

/* 
 * enums
 */

enum HRFS_VOL_STATE
    {
    HRFS_VOLUME_DEAD,
    HRFS_VOLUME_CREATED,
    HRFS_VOLUME_MOUNTED,
    HRFS_VOLUME_DYING
    };

#ifdef __cplusplus
extern "C" {
#endif

/*
 * typedefs
 */

/* The type used to represent a file's size. 64 bits, unsigned */
typedef INT64  fsize_t;

/* The type used to represent the generation number of an inode */
typedef UINT32  fgen_t;

/* Types used to represent the file owners' UID and GID values */
typedef UINT32  fid_t;

/* Type used to represent the number of hard links to a file */
typedef UINT16  linkCount_t;

/* Type used to represent the mode bits of a file */
typedef UINT16  fmode_t;

/* HRFS Volume State type */
typedef enum HRFS_VOL_STATE HRFS_VOL_STATE;

/* The on-disk representation of an HRFS inode */
typedef struct hrfs_inode_disk_struct
    {
    hrfsTime_t  ctime;       /* The last time the file attributes */
                             /* (inode) were changed. */
    hrfsTime_t  mtime;       /* The last time the file data was changed */
    fsize_t     size;        /* The size of the file */
    fgen_t      generation;  /* # of times inode has been allocated */
    fid_t       uid;         /* UID of value of the owner of the file */
    fid_t       gid;         /* GID of value of the owner of the file */
    UINT32      nBlocks;     /* The number of blocks associated with inode */
    UINT32      direct;      /* Direct block references */
    UINT32      indirect;    /* Indirect block references */
    UINT32      indirect2;   /* Doubly indirect block references */
    UINT32      indirect3;   /* Triply indirect block references */
    linkCount_t linkCount;   /* Number of hard links to file */
    fmode_t     mode;        /* Mode bits for file */
    u_char      state;       /* State:  free, allocated, to be deleted */
    char        reserved[3]; /* Pad out size to 64 bytes */
    } _WRS_PACK_ALIGN(1) HRFS_DISK_INODE, * HRFS_DISK_INODE_PTR;

/* The in-memory representation of an HRFS inode */
typedef struct hrfs_inode_struct
    {
    HRFS_DISK_INODE   iNodeData;
    UINT32            iNodeNumber;
    UINT32            dirSlot; /* directory slot from lookup op */
    } HRFS_INODE, * HRFS_INODE_PTR;

/* The representation of the HRFS inode journal */
typedef struct hrfs_inode_journal_struct
    {
    UINT64          transNumber;                         /* Transaction #. */
    UINT32          iNodeNumber[INODE_JOURNAL_ENTRIES];  /* I-Node #s. */
    char            reserved[28];                        /* For alignment. */
    HRFS_DISK_INODE iNodeData[INODE_JOURNAL_ENTRIES];    /* Inode data */
    } _WRS_PACK_ALIGN(1) HRFS_INODE_JOURNAL, * HRFS_INODE_JOURNAL_PTR;


typedef struct hrfs_tmr          /* HRFS Transaction Master Record */
    {
    UINT64    transNumber;       /* HRFS transaction number */
    UINT64    timeStamp;         /* HRFS timestamp */
    UINT32    numInodesToDelete;
    UINT32    numFreeInodes;
    UINT32    numFreeDataBlocks;
    UINT32    spare;
    } _WRS_PACK_ALIGN(1) HRFS_TMR;

/* 
 * The representation of the HRFS Super Block. The size of this structure must 
 * be a multiple of 8 
 */
typedef struct hrfs_super_block_struct
    {
    char      idString[8];  /* Identification or eyecatcher string */
    INT64     ctime;        /* time at which superblock was created. */
    UINT8     majorVers;    /* Major version number */
    UINT8     minorVers;    /* Minor version number */
    UINT16    blkSize2;     /* Block size as a power of 2. */
    UINT32    totalBlks;    /* Total # of blocks in fs (including offset). */

    UINT32    reservedBlks; /* Size of the reserved space at */
                            /* the start of the media. */

    UINT32    iNodeCount;   /* The number of iNodes this file */
                            /* system instantiation has. */

    UINT32    bgSize;       /* Block group size  (=dsSize + 1 for 1st iter) */
    UINT32    dsSize;       /* Data space size   (=bgSize - 1 for 1st iter) */
    UINT32    nBlkGroups;   /* Number of block groups. (1 for 1st iteration) */

    UINT32    fsbOff[2];    /* 1st & 2nd free space bitmap offsets */
    UINT32    fibOff[2];    /* 1st & 2nd free inode bitmap offsets */

    UINT32    itOff;        /* inode table offset */
    UINT32    ijOff;        /* inode journal offset */

    UINT32    tmOff[2];     /* 1st & 2nd transaction map offsets */
    UINT32    tmrOff[2];    /* 1st & 2nd transaction  master record offsets */

    UINT32    dsOff;        /* data space offset */
    UINT32    pad;          /* pad out structure */
    UINT32    crc;          /* superblock CRC */
    } _WRS_PACK_ALIGN(1) HRFS_SUPER_BLOCK, * HRFS_SUPER_BLOCK_PTR;

/* HRFS directory entry */
typedef struct hrfs_dirent
    {
    UINT32         iNodeNumber;      /* iNode corresponding to file */
    unsigned char  fileName[HRFS_MAX_FILENAME_LEN + 1];   /* File Name */
    } _WRS_PACK_ALIGN(1) HRFS_DIRENT, * HRFS_DIRENT_PTR;

/*
 * Fields that describe the physical layout of the backing media,
 * try to go in the volume descriptor.
 */

typedef struct hrfs_volume_desc      /* HRFS volume descriptor structure */
    {
    u_int                 magic;          /* value: HRFS_VOLUME_MAGIC */
    HRFS_VOL_STATE        state;          /* Created/Mounted/Dying/Dead */
    BOOL                  diskModified;   /* Set to TRUE when HRFS modifies */
                                          /* the disk */
    HRFS_SUPER_BLOCK *    pSuperBlk;      /* HRFS Super Block */
    device_t              device;         /* device associated with volume */
    sector_t              nSectors;       /* # of sectors on backing media */
    UINT32                sectorSize;     /* sector size of backing media */
    UINT32                sectorsPerBlk;  /* The number of sectors in a block */
    UINT32                sectorsPerBlk2; /* The number of sectors in a block */
                                          /* as a power of 2 */
    UINT32                blkSize;        /* block size in bytes */
    UINT32                blkCount;       /* # of blocks */
    int                   validTransSet;  /* valid transaction set: 0 or 1 */
    UINT64                validTransNo;   /* The transaction number of the */
                                          /* last set transaction point */
    UINT64                workingTransNo; /* The transaction number of the */
                                          /* current transaction. */
    UINT32                numInodesToDelete;
    UINT32                freeInodes;
    UINT32                freeDataBlks;
    struct mount *        pMount;
    UINT32                tmRead[2];      /* [0]: FSB, [1]: FIB */
    UINT32                tmWrite[2];     /* [0]: FSB, [1]: FIB */
    } HRFS_VOLUME_DESC;

typedef struct hrfs_dev           /* HRFS device structure */
    {
    HRFS_VOLUME_DESC  hrfsVolDesc; /* HRFS Volume Descriptor */

    u_char *          pSectorData; /* sector scratch-pad */
    SEM_ID            bioSem;      /* Binary semaphore for BIO/XBD calls */
    } HRFS_DEV;

/* externs */
extern STATUS hrfsSuperBlockRd (HRFS_DEV * devPtr);
extern UINT32 hrfsCksum (char * data, UINT32 crcIn, UINT32 size);
extern int hrfsInodePut(struct vnode *, HRFS_DEV *, HRFS_INODE_PTR);
extern int hrfsInodeJournalUpdate(struct vnode *, HRFS_DEV *, HRFS_INODE_PTR);

extern int  hrfsInodeGet       (struct vnode *);
extern int  hrfsInodeAlloc     (HRFS_DEV *, HRFS_INODE *, struct vattr *);
extern int  hrfsDataBlockAlloc (HRFS_DEV *, UINT32 *);
extern int  hrfsDataBlockFree  (HRFS_DEV *, UINT32);
extern int  hrfsInodeFree      (HRFS_DEV *, UINT32);

extern int  hrfsCommit (struct mount *);
extern int  hrfsMount  (struct mount *);
extern int  hrfsStat   (struct mount *, struct statvfs *);

extern int  hrfsInodeGetInternal (struct vnode *, HRFS_VOLUME_DESC *,
                                  HRFS_INODE *);
extern void hrfsInodeDiskHostConvert (HRFS_DISK_INODE *, HRFS_DISK_INODE *);
extern int  hrfsTransactionRollback  (struct mount *);

extern void hrfsFreeBufs (struct buf * pTrieBuf[], int start, int end);
extern int  hrfsTrieFindPhys (struct vnode * syncer_vp, UINT32 lbn,
                              HRFS_INODE_PTR iNodePtr,
                              HRFS_VOLUME_DESC * pVolDesc, UINT32 * pPbn,
                              struct buf * pTrieBuf[3]);
extern void hrfsVopInternalReadStrategy (struct vnode * pSyncer,
                                         struct buf * pBuf,
                                         struct buf * pTrieBuf[],
                                         UINT32	pbn);
extern int  hrfsDirEntFromSlot (struct vnode * pDirVnode,
                                struct buf ** pOutBuf,
                                HRFS_DIRENT ** pOutDirEnt);

extern UINT32 hrfsBitGet(unsigned char *, UINT32);

#ifdef HRFS_DEBUG
extern void hrfsInodePrint    (HRFS_INODE_PTR, char *);
extern void hrfsPrintSuperBlk (HRFS_SUPER_BLOCK_PTR);
extern void hrfsPrintSuperBlkRaw (HRFS_SUPER_BLOCK_PTR);
extern void hrfsPrintBmp         (unsigned char *, UINT32);
#endif

#ifdef __cplusplus
    }
#endif

#endif /* __INChrfsLibP */

